<!--表格组件-列设置组件-->
<template>
  <el-dialog
    destroy-on-close
    v-model="isShow"
    :title="$t('组件文本.表格列设置')"
    width="800"
    @close="closeSetting(false)"
  >
    <section class="main-section">
      <div class="section-left">
        <div class="section-title">
          {{ $t('组件文本.可选字段') }}（{{ $t('组件文本.共') }}
          {{ data.leftDataList.length }}
          {{ $t('组件文本.个') }}）
        </div>
        <div class="section-box">
          <div class="section-top">
            <el-checkbox
              v-model="data.leftCheckAll"
              :indeterminate="data.leftIndeterminate"
              @change="(bool) => checkAllChange(bool, true)"
            >
              {{ data.leftCheckedList.length }}/{{ data.leftDataList.length
              }}{{ $t('组件文本.个') }}
            </el-checkbox>
          </div>
          <div class="section-bottom">
            <el-input
              :placeholder="$t('基础文本.请搜索')"
              style="margin-bottom: 4px"
              v-model="data.leftSearchValue"
              :suffix-icon="Search"
              clearable
            />
            <el-scrollbar height="260px">
              <el-checkbox-group
                v-model="data.leftCheckedList"
                @change="(value) => checkedChange(value, true)"
              >
                <el-row style="width: 100%">
                  <el-col :span="8" v-for="item in leftData" :key="item.prop">
                    <el-checkbox :value="item.prop">
                      <div class="row-text">
                        <el-tooltip placement="top" :content="item.label">
                          {{ item.label }}
                        </el-tooltip>
                      </div>
                    </el-checkbox>
                  </el-col>
                </el-row>
              </el-checkbox-group>
            </el-scrollbar>
          </div>
        </div>
      </div>
      <div class="section-middle">
        <el-button size="small" @click="toRight">
          <el-icon><ArrowRight /></el-icon>
        </el-button>
        <el-button size="small" @click="toLeft">
          <el-icon><ArrowLeft /></el-icon>
        </el-button>
      </div>
      <div class="section-right">
        <div class="section-title">
          {{ $t('组件文本.可选字段') }}（{{ $t('组件文本.共') }}{{ data.rightDataList.length
          }}{{ $t('组件文本.个') }}）
        </div>
        <div class="section-box">
          <div class="section-top">
            <el-checkbox
              v-model="data.rightCheckAll"
              :indeterminate="data.rightIndeterminate"
              :disabled="rightData.length <= data.fixedData.length"
              @change="(bool) => checkAllChange(bool, false)"
            >
              {{ data.rightCheckedList.length }}/{{ data.rightDataList.length
              }}{{ $t('组件文本.个') }}
            </el-checkbox>
            <el-link style="font-size: 14px" :underline="false" @click="data.columnsConfig = true">
              <el-icon><Setting /></el-icon>
            </el-link>
          </div>
          <div class="section-bottom">
            <el-input
              placeholder="请输入搜索内容"
              style="margin-bottom: 10px"
              v-model="data.rightSearchValue"
              :suffix-icon="Search"
              clearable
            />
            <el-scrollbar height="260px">
              <!--<template v-for="item in rightData" :key="item.prop">-->
              <!--  <el-checkbox v-if="item.disabled" :label="item.label" :disabled="item.disabled" />-->
              <!--</template>-->
              <el-checkbox-group
                id="sortable"
                v-model="data.rightCheckedList"
                @change="(value) => checkedChange(value, false)"
              >
                <template v-for="item in rightData" :key="item.prop">
                  <!--<el-checkbox :value="item.prop" :disabled="item.disabled">-->
                  <el-checkbox :value="item.prop">
                    <div class="check-row">
                      <div class="row-text">
                        <el-tooltip placement="top" :content="item.label">
                          {{ item.label }}
                        </el-tooltip>
                      </div>
                      <el-link v-if="!data.rightSearchValue" class="row-btn" :underline="false">
                        <el-icon><Rank /></el-icon>
                      </el-link>
                    </div>
                  </el-checkbox>
                </template>
              </el-checkbox-group>
            </el-scrollbar>
          </div>
        </div>
      </div>
    </section>
    <template #footer>
      <span class="dialog-footer">
        <el-button link class="btn-left" @click="onReset">
          <el-icon><Refresh /></el-icon>
          {{ $t('组件文本.恢复默认') }}
        </el-button>
        <el-button @click="closeSetting(false)">{{ $t('基础文本.取消') }}</el-button>
        <el-button type="primary" @click="confirmSetting">{{ $t('基础文本.确定') }}</el-button>
      </span>
    </template>
  </el-dialog>

  <columnSettingDialog
    v-model="data.columnsConfig"
    v-model:pickColumn="data.pickColumn"
    :rightDataList="data.rightDataList"
  />
  <!--<el-dialog destroy-on-close v-model="data.columnsConfig" title="列配置" width="50vw">
    <el-table :data="data.rightDataList" size="small" border>
      <el-table-column label="功能列" prop="label" align="center" width="180" />
      <el-table-column label="排序" align="center" width="80">
        <template #default="{ row }">
          <el-switch size="small" v-model="row.sortable" />
        </template>
      </el-table-column>
      <el-table-column label="固定列" align="center">
        <template #default="{ row }">
          <el-select
            v-model="row.fixed"
            size="small"
            :placeholder="$t('基础文本.请选择')"
            clearable
          >
            <el-option label="left" value="left" />
            <el-option label="right" value="right" />
          </el-select>
        </template>
      </el-table-column>
    </el-table>

    <el-table :data="data.rightDataList" size="small" height="400">
      <el-table-column prop="label" label="列名" width="180" align="center" />
      <el-table-column prop="config" label="配置" align="center">
        <el-table-column label="列宽（px）" align="center" min-width="300">
          <template #default="{ row }">
            <el-input-number
              placeholder="该列宽度"
              size="small"
              style="width: 100%"
              v-model="row.width"
            />
            &lt;!&ndash;<el-row style="align-items: center; margin-bottom: 10px">
              <el-col :span="6" style="text-align: left">列宽</el-col>
              <el-col :span="18">
                <el-input-number
                  placeholder="该列宽度"
                  size="small"
                  style="width: 100%"
                  v-model="row.width"
                />
              </el-col>
            </el-row>
            <el-row style="align-items: center">
              <el-col :span="6" style="text-align: left">最小列宽</el-col>
              <el-col :span="18">
                <el-input-number
                  placeholder="该列宽度不会低于设定的值"
                  size="small"
                  style="width: 100%"
                  v-model="row.minWidth"
                />
              </el-col>
            </el-row>&ndash;&gt;
          </template>
        </el-table-column>
        <el-table-column label="排序" align="center" width="80">
          <template #default="{ row }">
            <el-switch size="small" v-model="row.sortable" />
          </template>
        </el-table-column>
        &lt;!&ndash;<el-table-column label="内部搜索" align="center" min-width="100">
          <template #header>
            内部搜索
            <el-tooltip
              content="开启前端分页时，该列数据是否可在右上的搜索框搜索出来"
              effect="dark"
              placement="top"
            >
              <el-icon><QuestionFilled /></el-icon>
            </el-tooltip>
          </template>
          <template #default="{ row }">
            <el-switch size="small" v-model="row.search" />
          </template>
        </el-table-column>&ndash;&gt;
        <el-table-column label="固定列" align="center">
          <template #default="{ row }">
            <el-select
              v-model="row.fixed"
              size="small"
              :placeholder="$t('基础文本.请选择')"
              clearable
            >
              <el-option label="left" value="left" />
              <el-option label="right" value="right" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="数据过滤" align="center">
          <template #default="{ row }">
            <el-select
              v-model="row.filter"
              size="small"
              :placeholder="$t('基础文本.请选择')"
              clearable
            >
              <el-option label="input" value="input" />
              <el-option label="select" value="select" />
              <el-option label="date" value="date" />
            </el-select>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
  </el-dialog>-->
</template>

<script setup>
import columnSettingDialog from './columnSettingDialog.vue';
import { Search } from '@element-plus/icons-vue';
import Sortable from 'sortablejs';

const { settingColumns } = defineProps({
  //获取表头数据的接口
  settingColumns: {
    type: Object,
    default: () => {
      return {
        getColumns: null, //获取表头接口
        getColumnsParams: {}, //接口入参
        setColumns: null, //保存设置的表头接口
        setColumnsParams: {}, //接口入参
      };
    },
  },
});
const isShow = defineModel('isShow');

const data = reactive({
  columnsConfig: false, //每列的配置弹窗
  fixedData: [], //固定显示在列设置右侧的数据
  pickColumn: [], //显示的功能列
  allColumns: [], //全部表头
  tableColumns: [], //表头
  defaultColumns: [], //默认的表头，恢复默认用

  leftCheckAll: false, //标记左侧是否已全选
  leftIndeterminate: false, //左侧的不确定状态，仅负责样式控制
  leftSearchValue: '', //左侧搜索框
  leftDataList: [], //左侧的数据
  leftCheckedList: [], //左侧选中的数据

  rightCheckAll: false, //标记右侧是否已全选
  rightIndeterminate: false, //右侧的不确定状态，仅负责样式控制
  rightSearchValue: '', //左侧搜索框
  rightDataList: [], //左侧的数据
  rightCheckedList: [], //右侧选中的数据
});
//配置的表格功能列
const typeColumns = ref([
  {
    label: '',
    type: 'selection',
    reserveSelection: true, //数据刷新后是否保留选中项
  },
  {
    label: '',
    type: 'radio',
  },
  {
    label: '',
    type: 'expand',
  },
  {
    label: '',
    type: 'drag',
  },
  {
    label: window.$t('基础文本.序号'),
    type: 'index',
  },
]);
const staticTypeColumns = ['selection', 'radio', 'expand', 'drag', 'index']; //功能列

//实际使用的左侧列表
const leftData = computed(() => {
  return data.leftDataList.filter((item) => item.label.includes(data.leftSearchValue));
});
//实际使用的右侧列表
const rightData = computed(() => {
  return data.rightDataList.filter((item) => item.label.includes(data.rightSearchValue));
});

//获取弹窗开启时的数据
watch(
  () => isShow.value,
  (newVal) => {
    if (newVal) {
      nextTick(() => {
        Sortable.create(document.getElementById('sortable'), {
          animation: 200, // 拖动时的元素的位置变化的动画时长，
          handle: '.row-btn',
          onEnd({ newIndex, oldIndex }) {
            // 首先删除原来的那一项，并且保存一份原来的那一项，因为splice返回的是一个数组，数组中的第一项就是删掉的那一项
            const currRow = data.rightDataList.splice(oldIndex, 1)[0];
            // 然后把这一项加入到新位置上
            data.rightDataList.splice(newIndex, 0, currRow);
          },
        });
      });
    }
  },
);

onMounted(() => {
  init();
});

/**
 * 初始化
 * */
const init = () => {
  settingColumns.getColumns(settingColumns.getColumnsParams).then((res) => {
    data.allColumns = res.data.allColumns;
    data.tableColumns = res.data.columns;
    data.defaultColumns = res.data.defaultColumns;

    //获取设置的功能列
    data.pickColumn = data.tableColumns.reduce((acc, obj) => {
      obj.type !== undefined && acc.push(obj.type);
      return acc;
    }, []);
    splitColumn(data.tableColumns);
  });
};
/**
 * 右侧全选复选框change事件
 * @bool {boolean} 是否全选
 * @type {boolean} true为左侧列表，false为右侧列表
 * */
const checkAllChange = (bool, type) => {
  data[(type && 'leftCheckedList') || 'rightCheckedList'] = bool
    ? (type && data.leftDataList.map((item) => item.prop)) || //左侧全选的处理
      data.rightDataList //右侧全选。因为右侧有固定显示列不允许勾选需要过滤禁选项
        .filter((item) => data.fixedData.every((el) => el.prop !== item.prop))
        .map((item) => item.prop)
    : [];

  data[(type && 'leftIndeterminate') || 'rightIndeterminate'] = false;
};
/**
 * 右侧复选框列表change事件
 * @value {array} 勾选的数据
 * @type {boolean} true为左侧列表，false为右侧列表
 * */
const checkedChange = (value, type) => {
  const dataListLen = data[(type && 'leftDataList') || 'rightDataList'].length;
  const checkedCount = value.length;

  data[(type && 'leftCheckAll') || 'rightCheckAll'] = checkedCount === dataListLen;
  data[(type && 'leftIndeterminate') || 'rightIndeterminate'] =
    checkedCount > 0 && checkedCount < dataListLen;
};
/**
 * 右移按钮，左侧勾选的数据移动到右侧
 * */
const toRight = () => {
  data.leftCheckedList.map((el) => {
    let i = data.leftDataList.findIndex((cel) => cel.prop === el);
    i > -1 && data.rightDataList.push(data.leftDataList.splice(i, 1)[0]);
  });

  //置空左侧选中
  data.leftCheckedList = [];
  data.leftIndeterminate = false;
  data.leftCheckAll = false;
};
/**
 * 左移按钮，右侧勾选的数据移动到左侧
 * */
const toLeft = () => {
  data.rightCheckedList.map((el) => {
    let i = data.rightDataList.findIndex((cel) => cel.prop === el);
    i > -1 && data.leftDataList.push(data.rightDataList.splice(i, 1)[0]);
  });

  //置空右侧选中
  data.rightCheckedList = [];
  data.rightIndeterminate = false;
  data.rightCheckAll = false;
};
/**
 * 恢复默认
 * */
const onReset = () => {
  resetPick();
  splitColumn(data.defaultColumns);
};
/**
 * 关闭弹窗
 * @flag {boolean} 是否点击了确认按钮
 * */
const closeSetting = (flag) => {
  if (!isShow.value) return; //防止重复触发
  isShow.value = false;
  resetPick();
  flag && init();
};
/**
 * 确认
 * */
const confirmSetting = () => {
  let arr = []; //要展示的功能列
  typeColumns.value.map((item) => {
    data.pickColumn.includes(item.type) && arr.push(item);
  });

  const columns = [...arr, ...data.rightDataList]; //组合出完整的要保存的列
  settingColumns
    .setColumns({
      ...settingColumns.setColumnsParams,
      columns: JSON.stringify(columns),
    })
    .then((res) => {
      emit('confirmSetting', columns);
      closeSetting(true);
    });
};
/**
 * 切割表头分为左右
 * @columns {array} 右侧使用的表头
 * */
const splitColumn = (columns) => {
  const propList = new Set(columns.map((i) => i.prop));
  data.leftDataList = data.allColumns.filter((item) => !propList.has(item.prop));
  data.rightDataList = columns.filter((col) => !col.type); //过滤掉复选框等这些功能列
};
/**
 * 重置选择的数据
 * */
const resetPick = () => {
  //初始化左侧
  data.leftSearchValue = '';
  data.leftCheckedList = [];
  data.leftIndeterminate = false;
  data.leftCheckAll = false;

  //初始化右侧
  data.rightSearchValue = '';
  data.rightCheckedList = [];
  data.rightIndeterminate = false;
  data.rightCheckAll = false;
};
const emit = defineEmits(['confirmSetting']);
</script>

<style lang="less" scoped>
.main-section {
  display: flex;
  width: 760px;
  height: 400px;
  .section-left {
    width: 460px;
    height: 100%;
    flex-shrink: 0;
    .section-title {
      height: 40px;
      width: 100%;
      line-height: 40px;
    }
    .section-box {
      height: calc(100% - 40px);
      width: 100%;
      border: 1px solid var(--el-border-color-light);
      border-radius: 4px;
      .section-top {
        padding: 4px 10px 2px 10px;
        border-bottom: 1px solid var(--el-border-color-light);
      }
      .section-bottom {
        padding: 8px 10px;
        .row-text {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          display: inline-block;
          width: 120px;
        }
      }
    }
  }
  .section-middle {
    height: 100%;
    width: 100%;
    flex-shrink: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    .el-button {
      margin: 0 0 8px 0;
      padding: 10px 6px;
    }
  }
  .section-right {
    width: 248px;
    height: 100%;
    flex-shrink: 0;
    .section-title {
      height: 40px;
      width: 100%;
      line-height: 40px;
    }
    .section-box {
      height: calc(100% - 40px);
      width: 100%;
      border: 1px solid var(--el-border-color-light);
      border-radius: 4px;
      .section-top {
        display: flex;
        justify-content: space-between;
        padding: 4px 10px 2px 10px;
        border-bottom: 1px solid var(--el-border-color-light);
      }
      .section-bottom {
        padding: 8px 4px 8px 10px;
        .el-checkbox {
          width: 100%;
          margin-right: 0;
          :deep(.el-checkbox__label) {
            width: calc(100% - 30px);
            padding-right: 6px;
          }
        }
        .check-row {
          width: 100%;
          background: var(--el-fill-color-blank);
          .row-mover {
            margin-right: 6px;
          }
          .row-text {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            display: inline-block;
            width: 154px;
          }
          .row-btn {
            float: right;
          }
        }
      }
    }
  }
}
.el-checkbox-group {
  overflow-x: hidden;
  box-sizing: border-box;
}
.dialog-footer {
  .btn-left {
    float: left;
  }
}
</style>
